package com.cxb.demotest.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Objects;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.util.CollectionUtils;

public class DateUtil {

    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String DATE_FORMAT_TWO = "yyyy/MM/dd";
    public static final String DATE_MINUTE_FORMAT = "HH:mm";
    public static final String DATE_MINUTE_SECOND_FORMAT = "HH:mm:ss";
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_TIME_FORMAT_APP = "yyyy-MM-dd HH:mm";
    public static final String DATESTYLE_YYYYMMDD = "yyyyMMdd";
    public static final String SIMPLE_BOARD_FORMAT = "MM-dd HH:mm";
    public static final String SMS_FORMAT = "yyyy年MM月dd日";
    public static final String DATE_TIME_NO_SEPARATION_FORMAT = "yyyyMMddHHmmss";
    public static final String DATE_TIME_START_OF_DAY_FORMAT = "yyyy-MM-dd 00:00:00";
    public static final String DATE_TIME_END_OF_DAY_FORMAT = "yyyy-MM-dd 23:59:59";

    /**
     * 获取当前时间戳（毫秒）
     */
    public static long getCurTimeMs() {
        return System.currentTimeMillis();
    }

    /**
     * 格式化时间戳
     */
    public static Date formatTimeStamp(long timestamp, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Long time = timestamp * 1000;
        String d = sdf.format(time);
        Date date = null;
        try {
            date = sdf.parse(d);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    public static String parseDateTimeStr(Date date, String pattern) {
        if (Objects.isNull(date)) {
            return null;
        }
        return DateFormatUtils.format(date, pattern);
    }

    public static String parseDateTimeStr(Date date) {
        if (Objects.isNull(date)) {
            return "";
        }
        return DateFormatUtils.format(date, DATE_TIME_FORMAT);
    }

    public static String parseDateTimeStr(LocalDateTime localDateTime) {
        if (Objects.isNull(localDateTime)) {
            return null;
        }
        return format(localDateTime, DATE_TIME_FORMAT);
    }

    public static String parseDateTimeStr(LocalDateTime localDateTime, String format) {
        if (Objects.isNull(localDateTime)) {
            return null;
        }
        return format(localDateTime, format);
    }

    public static String format(LocalDateTime localDateTime, String format) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
        return localDateTime.format(df);
    }

    public static String parseDateTimeStr(LocalDate localDate) {
        if (Objects.isNull(localDate)) {
            return null;
        }
        return format(localDate, DATE_FORMAT);
    }

    public static String parseDateTimeStr(LocalDate localDate, String format) {
        if (Objects.isNull(localDate)) {
            return null;
        }
        return format(localDate, format);
    }

    public static String format(LocalDate localDate, String format) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
        return localDate.format(df);
    }

    /**
     * 时间转时间戳字符串
     *
     * @param date Date 对象
     * @return 时间戳字符串
     */
    public static String parseDateAsTimestampMillStr(Date date) {
        if (Objects.isNull(date)) {
            return "";
        }

        return date.getTime() + "";
    }

    public static String parseDateTimeStr(long seconds) {
        return DateFormatUtils.format(seconds*1000, DATE_TIME_FORMAT);
    }

    public static String parseDateStr(long seconds) {
        return DateFormatUtils.format(seconds*1000, DATE_FORMAT);
    }

    public static Date parseDate(String dateTimeStr) {


                try {
                    if (DATE_FORMAT.length() == dateTimeStr.length()) {
                        return DateUtils.parseDate(dateTimeStr, DATE_FORMAT);
                    } else if (DATE_TIME_FORMAT.length() == dateTimeStr.length()) {
                        return DateUtils.parseDate(dateTimeStr, DATE_TIME_FORMAT);
                    } else if (DATE_TIME_FORMAT_APP.length() == dateTimeStr.length()) {
                        return DateUtils.parseDate(dateTimeStr, DATE_TIME_FORMAT_APP);
                    } else {
                        return null;
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            return null;

    }

    public static long addYears(Date date, int amount) {
        return DateUtils.addYears(date, amount).getTime();
    }

    public static long addMonths(Date date, int amount) {
        return DateUtils.addMonths(date, amount).getTime();
    }

    public static long addDays(Date date, int amount) {
        return DateUtils.addDays(date, amount).getTime();
    }

    public static long addHours(Date date, int amount) {
        return DateUtils.addHours(date, amount).getTime();
    }

    public static long addMinutes(Date date, int amount) {
        return DateUtils.addMinutes(date, amount).getTime();
    }

    public static long addSeconds(Date date, int amount) {
        return DateUtils.addSeconds(date, amount).getTime();
    }

    public static String parseDateTimeStrNoSeparation(Date date) {
        if (Objects.isNull(date)) {
            return "";
        }
        return DateFormatUtils.format(date, DATE_TIME_NO_SEPARATION_FORMAT);
    }

    public static String parseDateStr(Date date) {
        if (Objects.isNull(date)) {
            return "";
        }
        return DateFormatUtils.format(date, DATE_FORMAT);
    }

    public static String parseStartOfDay(Date date) {
        if (Objects.isNull(date)) {
            return "";
        }

        Calendar ca = Calendar.getInstance();
        ca.setTime(date);

        SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_TIME_START_OF_DAY_FORMAT);

        return dateFormat.format(ca.getTime());
    }

    public static String parseEndOfDay(Date date) {
        if (Objects.isNull(date)) {
            return "";
        }

        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.DATE, 1); //日期加1

        SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_TIME_START_OF_DAY_FORMAT);

        return dateFormat.format(ca.getTime());
    }

    public static long getMinutes(Date startDate, Date endDate) {
        long between = (endDate.getTime() - startDate.getTime()) / 1000;
        long min = between / 60;
        return min;
    }

    public static Date getMaxDate(List<Date> dateList) {
        if (CollectionUtils.isEmpty(dateList)) {
            return null;
        }
        Date maxDate = dateList.get(0);
        for (Date date : dateList) {
            if (date.compareTo(maxDate) == 1) {
                maxDate = date;
            }
        }
        return maxDate;
    }

    /**
     * 获取两个时间点的月份差
     * @param dt1 第一个时间点
     * @param dt2 第二个时间点
     * @return int，即需求的月数差
     */
    public static int monthDiff(LocalDateTime dt1, LocalDateTime dt2){
        //获取第一个时间点的月份
        int month1 = dt1.getMonthValue();
        //获取第一个时间点的年份
        int year1 = dt1.getYear();
        //获取第一个时间点的月份
        int month2 = dt2.getMonthValue();
        //获取第一个时间点的年份
        int year2 = dt2.getYear();
        //返回两个时间点的月数差
        return (year2 - year1) *12 + (month2 - month1);
    }

    public static int dateDiff(LocalDateTime dt1,LocalDateTime dt2){
        //获取第一个时间点的时间戳对应的秒数
        long t1 = dt1.toEpochSecond(ZoneOffset.ofHours(0));
        //获取第一个时间点在是1970年1月1日后的第几天
        long day1 = t1 /(60*60*24);
        //获取第二个时间点的时间戳对应的秒数
        long t2 = dt2.toEpochSecond(ZoneOffset.ofHours(0));
        //获取第二个时间点在是1970年1月1日后的第几天
        long day2 = t2/(60*60*24);
        //返回两个时间点的天数差
        return (int)(day2 - day1);
    }

    public static LocalDateTime toLocalDateTime(Date date) {
        if (Objects.isNull(date)) {
            return null;
        }

        DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);
        return LocalDateTime.parse(parseDateTimeStr(date), df);
    }

    // 获取本周的开始时间
    @SuppressWarnings("unused")
    public static String getBeginDayOfWeek() {
        Date date = new Date();
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return parseStartOfDay(cal.getTime());
    }

    // 获取本月的开始时间
    public static String getBeginDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        return parseStartOfDay(calendar.getTime());
    }

    // 获取今年是哪一年
    public static Integer getNowYear() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }

    // 获取本月是哪一月
    public static int getNowMonth() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(2) + 1;
    }

    // 获取本年的开始时间
    public static String getBeginDayOfYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);
        return parseStartOfDay(cal.getTime());
    }

    public static  LocalDateTime timeStampTo(Long timeStamp){
        Instant instant = Instant.ofEpochMilli(timeStamp);
        return LocalDateTime.ofInstant(instant, ZoneOffset.of("+8"));
    }
}
